//    Copyright (C) Kherty.  All rights reserved.
using System.Diagnostics.Contracts;
using System.Reflection;
using OpenLS.Core.Serialization;
using OpenLS.Drawing;
using System.ComponentModel;

namespace OpenLS.Chart
{
    public class TrendLine : IOfficeXmlSerializable, INotifyPropertyChanged, IShape
    {
        internal const string xmlName = "trendline";
        private ExtensionElement _extension;

        private ShapeProperties _spPr;
        private double _backward;
        private bool _dispEq;
        private bool _dispRSqr;
        private double _forward;
        private double _intercept;
        private string _name;
        private int? _order;
        private int? _period;
        private TrendlineLabel _trendlineLbl;
        private TrendlineType _trendlineType;

        public ShapeProperties ShapeProperties
        {
            get { return _spPr; }
            set { _spPr = value; notifyPropertyChanged("ShapeProperties"); }
        }


        public ExtensionElement Extension
        {
            get { return _extension; }
            set { _extension = value; notifyPropertyChanged("Extension"); }
        }


        public string Name
        {
            get { return _name; }
            set { _name = value; notifyPropertyChanged("Name"); }
        }

        public TrendlineType Type
        {
            get { return _trendlineType; }
            set { _trendlineType = value; notifyPropertyChanged("Type"); }
        }

        public int? Order
        {
            get { return _order; }
            set { _order = value; notifyPropertyChanged("Order"); }
        }

        public int? Period
        {
            get { return _period; }
            set { _period = value; notifyPropertyChanged("Period"); }
        }

        public double Forward
        {
            get { return _forward; }
            set { _forward = value; notifyPropertyChanged("Forward"); }
        }

        public double Backward
        {
            get { return _backward; }
            set { _backward = value; notifyPropertyChanged("Backward");}
        }

        public double Intercept
        {
            get { return _intercept; }
            set { _intercept = value; notifyPropertyChanged("Intercept"); }
        }

        public bool DisplayRSquaredValue
        {
            get { return _dispRSqr; }
            set { _dispRSqr = value; notifyPropertyChanged("DisplayRSquaredValue"); }
        }

        public bool DisplayEquation
        {
            get { return _dispEq; }
            set { _dispEq = value; notifyPropertyChanged("DisplayEquation"); }
        }

        public TrendlineLabel Label
        {
            get { return _trendlineLbl; }
            set { _trendlineLbl = value; notifyPropertyChanged("Label"); }
        }

        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (var c = context.Read(xmlName))
            {
                Name = c.ReadOptionalElementString("name");
                ShapeProperties = c.ReadOptionalElement<ShapeProperties>("spPr"); //\\not documented
                Type = c.ReadElementEnumAttribute<TrendlineType>("trendlineType");
                Order = c.ReadOptionalElementIntegerAttribute("order");
                Period = c.ReadOptionalElementIntegerAttribute("period");
                Forward = c.ReadOptionalElementDoubleAttribute("forward", 0);
                _backward = c.ReadOptionalElementDoubleAttribute("backward", 0);
                Intercept = c.ReadOptionalElementDoubleAttribute("intercept", 0);
                DisplayRSquaredValue = c.ReadOptionalElementBooleanAttribute("dispRSqr", false);
                DisplayEquation = c.ReadOptionalElementBooleanAttribute("dispEq", false);
                Label = c.ReadOptionalElement<TrendlineLabel>("trendlineLbl");
                Extension = c.ReadOptionalElement<ExtensionElement>("extLst");
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (WriteContext c = context.Write(xmlName))
            {
                c.WriteOptionalElementString("name", Name);
                c.WriteOptionalElement(ShapeProperties);
                c.WriteElementEnumAttribute("trendlineType", Type);
                c.WriteOptionalElementIntegerAttribute("order", Order);
                c.WriteOptionalElementIntegerAttribute("period", Period);
                c.WriteOptionalElementDoubleAttribute("forward", "val", Forward, 0);
                c.WriteOptionalElementDoubleAttribute("backward", "val", _backward, 0);
                c.WriteOptionalElementDoubleAttribute("intercept", "val", Intercept, 0);
                c.WriteOptionalElementBooleanAttribute("dispRSqr", DisplayRSquaredValue);
                c.WriteOptionalElementBooleanAttribute("dispEq", DisplayEquation);
                c.WriteOptionalElement(Label);
                c.WriteOptionalElement(Extension);
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        void notifyPropertyChanged(string propertyName)
        {
            Contract.Requires(GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null);
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}